package com.work.common.base;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class WorkThreadPool {

    private static final String DEFAULT_THREAD_POOL_NAME = "work-thread-pool";

    public static ThreadPoolExecutor getThreadPool() {
        return getThreadPool(10, 20, 60, TimeUnit.SECONDS, 5000, DEFAULT_THREAD_POOL_NAME);
    }

    public static ThreadPoolExecutor getThreadPool(String name) {
        return getThreadPool(10, 20, 60, TimeUnit.SECONDS, 5000, name);
    }

    public static ThreadPoolExecutor getThreadPool(int core, int max, int time,
                                                   TimeUnit timeUnit, int queueSize) {
        return getThreadPool(core, max, time, timeUnit, queueSize, DEFAULT_THREAD_POOL_NAME);
    }

    public static ThreadPoolExecutor getThreadPool(
            int core, int max, int time,
            TimeUnit timeUnit, int queueSize,
            String name) {
        return new ThreadPoolExecutor(
                core, max, time,
                timeUnit,
                new LinkedBlockingDeque<>(queueSize),
                new WorkThreadPoolFactory(name)
        );
    }

    private static class WorkThreadPoolFactory implements ThreadFactory {
        private final AtomicInteger count = new AtomicInteger(1);
        private final String name;

        public WorkThreadPoolFactory(String name) {
            this.name = name;
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setName(this.name + "-" + count.getAndIncrement());
            if (thread.isDaemon()) {
                thread.setDaemon(false);
            }
            if (thread.getPriority() != Thread.NORM_PRIORITY) {
                thread.setPriority(Thread.NORM_PRIORITY);
            }
            return thread;
        }
    }
}
